/**
 * Java运算符教学案例
 * 本案例演示了Java中各种运算符的使用方法和注意事项
 */
public class OperatorsExample {
    
    public static void main(String[] args) {
        OperatorsExample example = new OperatorsExample();
        
        example.demonstrateArithmeticOperators();      // 算术运算符演示
        example.demonstrateAssignmentOperators();      // 赋值运算符演示
        example.demonstrateComparisonOperators();      // 比较运算符演示
        example.demonstrateLogicalOperators();         // 逻辑运算符演示
        example.demonstrateBitwiseOperators();         // 位运算符演示
        example.demonstrateTernaryOperator();          // 条件运算符演示
        example.demonstrateOperatorPrecedence();       // 运算符优先级演示
    }
    
    /**
     * 演示算术运算符的使用
     * 难点：自增自减运算符的前缀和后缀形式区别
     * 注意事项：
     * 1. 整数除法会截断小数部分
     * 2. 取模运算结果的符号与被除数相同
     */
    public void demonstrateArithmeticOperators() {
        System.out.println("=== 算术运算符演示 ===");
        int a = 20;
        int b = 10;
        
        System.out.println("a = " + a + ", b = " + b);
        System.out.println("加法 (a + b) = " + (a + b));     // 加法
        System.out.println("减法 (a - b) = " + (a - b));     // 减法
        System.out.println("乘法 (a * b) = " + (a * b));     // 乘法
        System.out.println("除法 (a / b) = " + (a / b));     // 除法 - 注意整数除法截断小数
        System.out.println("取模 (a % b) = " + (a % b));     // 取模
        
        // 自增自减运算符演示
        int c = 5;
        System.out.println("\n自增/自减运算符演示:");
        System.out.println("c = " + c);
        System.out.println("前缀自增 (++c) = " + (++c));    // 先自增再使用
        System.out.println("后缀自增 (c++) = " + (c++));    // 先使用再自增
        System.out.println("自增后的c值 = " + c);
        System.out.println("前缀自减 (--c) = " + (--c));    // 先自减再使用
        System.out.println("后缀自减 (c--) = " + (c--));    // 先使用再自减
        System.out.println("自减后的c值 = " + c);
        System.out.println();
    }
    
    /**
     * 演示赋值运算符的使用
     * 难点：复合赋值运算符的计算顺序
     * 注意事项：
     * 1. 复合赋值运算符会自动进行类型转换
     * 2. 赋值表达式本身也有值
     */
    public void demonstrateAssignmentOperators() {
        System.out.println("=== 赋值运算符演示 ===");
        int a = 10;
        System.out.println("初始值 a = " + a);
        
        a += 5;  // 等价于 a = a + 5
        System.out.println("a += 5 后 a = " + a);
        
        a -= 3;  // 等价于 a = a - 3
        System.out.println("a -= 3 后 a = " + a);
        
        a *= 2;  // 等价于 a = a * 2
        System.out.println("a *= 2 后 a = " + a);
        
        a /= 4;  // 等价于 a = a / 4
        System.out.println("a /= 4 后 a = " + a);
        
        a %= 3;  // 等价于 a = a % 3
        System.out.println("a %= 3 后 a = " + a);
        System.out.println();
    }
    
    /**
     * 演示比较运算符的使用
     * 难点：对象比较时使用==和equals的区别
     * 注意事项：
     * 1. ==比较基本类型时比较值，比较对象时比较引用
     * 2. 比较结果总是boolean类型
     */
    public void demonstrateComparisonOperators() {
        System.out.println("=== 比较运算符演示 ===");
        int a = 10;
        int b = 20;
        
        System.out.println("a = " + a + ", b = " + b);
        System.out.println("等于 (a == b): " + (a == b));        // 等于
        System.out.println("不等于 (a != b): " + (a != b));      // 不等于
        System.out.println("大于 (a > b): " + (a > b));          // 大于
        System.out.println("小于 (a < b): " + (a < b));          // 小于
        System.out.println("大于等于 (a >= b): " + (a >= b));     // 大于等于
        System.out.println("小于等于 (a <= b): " + (a <= b));     // 小于等于
        System.out.println();
    }
    
    /**
     * 演示逻辑运算符的使用
     * 难点：短路求值的特性
     * 注意事项：
     * 1. &&和||具有短路特性，可以避免不必要的计算
     * 2. &和|没有短路特性，会计算所有操作数
     */
    public void demonstrateLogicalOperators() {
        System.out.println("=== 逻辑运算符演示 ===");
        boolean x = true;
        boolean y = false;
        
        System.out.println("x = " + x + ", y = " + y);
        System.out.println("逻辑与 (x && y): " + (x && y));   // 逻辑与 - 短路
        System.out.println("逻辑或 (x || y): " + (x || y));   // 逻辑或 - 短路
        System.out.println("逻辑非 (!x): " + (!x));           // 逻辑非
        
        // 短路求值演示
        System.out.println("\n短路求值演示:");
        int num = 5;
        // 由于false && ...，右侧不会执行，避免了除零错误
        boolean result = false && (num / 0 == 0); 
        System.out.println("短路求值结果: " + result);
        System.out.println();
    }
    
    /**
     * 演示位运算符的使用
     * 难点：位运算的二进制表示理解
     * 注意事项：
     * 1. 位运算直接对整数的二进制位进行操作
     * 2. 左移n位相当于乘以2的n次方，右移n位相当于除以2的n次方
     */
    public void demonstrateBitwiseOperators() {
        System.out.println("=== 位运算符演示 ===");
        int a = 5;   // 二进制: 0101
        int b = 3;   // 二进制: 0011
        
        System.out.println("a = " + a + " (二进制: 0101)");
        System.out.println("b = " + b + " (二进制: 0011)");
        System.out.println("按位与 (a & b) = " + (a & b) + " (二进制: 0001)");   // 按位与
        System.out.println("按位或 (a | b) = " + (a | b) + " (二进制: 0111)");   // 按位或
        System.out.println("按位异或 (a ^ b) = " + (a ^ b) + " (二进制: 0110)"); // 按位异或
        System.out.println("按位取反 (~a) = " + (~a) + " (二进制: 1010)");       // 按位取反
        System.out.println("左移 (a << 1) = " + (a << 1) + " (二进制: 1010)");   // 左移
        System.out.println("右移 (a >> 1) = " + (a >> 1) + " (二进制: 0010)");   // 右移
        System.out.println();
    }
    
    /**
     * 演示条件运算符（三元运算符）的使用
     * 难点：嵌套使用时的可读性问题
     * 注意事项：
     * 1. 条件运算符是唯一一个三元运算符
     * 2. 表达式1和表达式2的类型必须兼容
     */
    public void demonstrateTernaryOperator() {
        System.out.println("=== 条件运算符（三元运算符）演示 ===");
        int a = 10;
        int b = 20;
        
        // 使用三元运算符找出最大值
        int max = (a > b) ? a : b;
        System.out.println("a = " + a + ", b = " + b);
        System.out.println("使用三元运算符找出最大值: " + max);
        
        // 字符串条件判断
        String result = (a % 2 == 0) ? "偶数" : "奇数";
        System.out.println("a是: " + result);
        System.out.println();
    }
    
    /**
     * 演示运算符优先级
     * 难点：多个运算符混合使用时的计算顺序
     * 注意事项：
     * 1. 使用括号可以明确指定计算顺序，提高代码可读性
     * 2. 不要过分依赖运算符优先级，适当使用括号
     */
    public void demonstrateOperatorPrecedence() {
        System.out.println("=== 运算符优先级演示 ===");
        int a = 10;
        int b = 5;
        int c = 2;
        
        // 乘法运算符优先级高于加法
        int result1 = a + b * c;  // 等价于 a + (b * c) = 10 + (5 * 2) = 20
        System.out.println("a + b * c = " + a + " + " + b + " * " + c + " = " + result1);
        
        // 使用括号改变优先级
        int result2 = (a + b) * c;  // (10 + 5) * 2 = 30
        System.out.println("(a + b) * c = (" + a + " + " + b + ") * " + c + " = " + result2);
        
        // 复杂表达式
        boolean result3 = a > b && b < c || c == 2;
        System.out.println("a > b && b < c || c == 2: " + result3);
        System.out.println("计算顺序: (a > b) && (b < c) || (c == 2) => true && false || true => false || true => true");
        System.out.println();
    }
}